module es {
    /**
     *  第三方消息派发工具类
     */
    export class Third {

        private static _handls: {
            [key: string]: {
                caller: any,
                handl: Function,
                once?: boolean
            }[]
        } = {};


        /**
         * 监听事件
         * @param event 事件名称
         * @param caller 作用域
         * @param handl 回调方法
         */
        public static on(event: string, caller: any, handl: Function): void {

            if (undefined == Third._handls[event]) {
                Third._handls[event] = [{ caller, handl }];
            }
            else {
                let evlist = Third._handls[event];
                for (let ev of evlist) {
                    if (ev.caller == caller && ev.handl == handl) {
                        console.log("############## Repeat listening", event, caller, handl);
                        return;
                    }
                }
                Third._handls[event].push({ caller, handl });
            }
        }

        /**
         * 注册节点的特定事件类型回调，回调会在第一时间被触发后删除自身
         * @param event 事件名称
         * @param caller 作用域
         * @param handl 回调方法
         */
        public static once(event: string, caller: any, handl: Function): void {
            if (undefined == Third._handls[event]) {

                Third._handls[event] = [{ caller, handl, once: true }];

            }
            else {

                Third._handls[event].push({ caller, handl, once: true });
            }
        }

        /**
         * 移除监听
         * @param event 事件名称
         * @param caller 作用域 如果忽略 则移除所有该事件的监听 off("show");//所有show事件相关监听都会被移除
         * @param handl 回调方法 如果忽略 则移除该事件列表里 所有caller相关的方法  off("show",this);// this作用域下所有对show的监听都会被移除
         */
        public static off(event: string, caller: any = undefined, handl: Function = undefined): void {

            //获取事件队列
            const list = Third._handls[event];

            //遍历所有事件
            if (list && list instanceof Array) {

                //移除所有当前事件的监听
                if (undefined == caller) {
                    Third._handls[event] = [];
                    return;
                }

                let e = null;
                for (let i = 0; i < list.length; i++) {

                    e = list[i];

                    //移除对应事件
                    if (e.caller == caller && (undefined == handl || handl == e.handl)) {
                        //交换指针 移除尾部
                        list.splice(i--, 1);
                    }
                }
            }
        }


        /**
         * 移除监听者的所有事件监听 
         * @param caller 监听者 如果为null 则进行clear   offall(); 事件池归零
         */
        public static offall(caller: any = undefined) {
            if (!caller) {

                Third._handls = {};
            }
            else {
                //遍历所有事件链表
                for (let k in Third._handls) {
                    const list = Third._handls[k];
                    if (list && list instanceof Array) {
                        for (let i = 0; i < list.length; i++) {
                            //移除对应事件
                            if (list[i].caller == caller) {
                                list.splice(i--, 1);
                            }
                        }
                    }
                }
            }
        }

        /**
         * 派发事件
         * @param event 事件
         * @param params 可变参列表  do("show",true);   do("show",true,data);  do("show",data,true,"hello world",1234567890);
         */
        public static do(event: string, ...params: any[]) {

            const list = Third._handls[event];
            if (list && list instanceof Array) {

                let t = null;
                for (let i = 0; i < list.length; i++) {

                    //触发回调
                    t = list[i];
                    t.handl.call(t.caller, ...params);

                    //仅触发一次 则触发后移除
                    if (t.once) {
                        list.splice(i--, 1);
                    }
                }
            }

        }

    }
}